﻿// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.ComponentModel;

namespace System.Windows.Forms;

/// <summary>
///  Provides a type converter to convert state image index values from one data type to another.
/// </summary>
public class ListViewItemStateImageIndexConverter : ImageIndexConverter
{
    /// <summary>
    ///  Gets a value that indicates whether a none or <see langword="null" /> value
    ///  is valid in the <see cref="TypeConverter.StandardValuesCollection" /> collection.
    /// </summary>
    /// <value>
    ///  Always returns <see langword="false" /> to indicate that a none or
    ///  <see langword="null" /> value isn't valid in the standard values collection.
    /// </value>
    protected override bool IncludeNoneAsStandardValue
    {
        get
        {
            return false;
        }
    }

    /// <summary>
    ///  Retrieves a collection containing a set of standard values for the data type this validator is designed for.
    /// </summary>
    /// <param name="context">
    ///  An object that provides a format context, which can be used to extract additional
    ///  information about the environment this type converter is being invoked from.
    ///  This parameter or its properties can be <see langword="null" />.
    /// </param>
    /// <returns>
    ///  A collection that holds a standard set of valid index values.If no image list is found,
    ///  this collection contains a single object with a value of -1. This method returns<see langword="null" />
    ///  if the data type doesn't support a standard set of values.
    /// </returns>
    public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext? context)
    {
        if (context is not null && context.Instance is not null)
        {
            object instance = context.Instance;

            ImageList? imageList = null;

            PropertyDescriptorCollection listViewItemProps = TypeDescriptor.GetProperties(instance);
            PropertyDescriptor? listViewProp = listViewItemProps["ListView"];

            if (listViewProp is not null)
            {
                // Grab the ListView property off of the TreeNode.
                object? listViewInstance = listViewProp.GetValue(instance);

                if (listViewInstance is not null)
                {
                    // Get the ImageList property from the ListView and set it to be the currentImageList.
                    PropertyDescriptorCollection listViewProps = TypeDescriptor.GetProperties(listViewInstance);
                    PropertyDescriptor? listViewImageListProperty = listViewProps["StateImageList"];
                    if (listViewImageListProperty is not null)
                    {
                        imageList = (ImageList?)listViewImageListProperty.GetValue(listViewInstance);
                    }
                }
            }

            if (imageList is not null)
            {
                // Create array to contain standard values
                object[] values;
                int nImages = imageList.Images.Count;
                if (IncludeNoneAsStandardValue)
                {
                    values = new object[nImages + 1];
                    values[nImages] = ImageList.Indexer.DefaultIndex;
                }
                else
                {
                    values = new object[nImages];
                }

                // Fill in the array
                for (int i = 0; i < nImages; i++)
                {
                    values[i] = i;
                }

                return new StandardValuesCollection(values);
            }
        }

        if (IncludeNoneAsStandardValue)
        {
            return new StandardValuesCollection(new object[] { ImageList.Indexer.DefaultIndex });
        }
        else
        {
            return new StandardValuesCollection(Array.Empty<object>());
        }
    }
}
